package net.child.chess.pieces;

import java.util.List;
import net.child.chess.R;
import net.child.chess.utils.ChessDef;
import net.child.chess.utils.Move;
import net.child.chess.utils.Position;

public class King extends Piece 
{
	public King(ChessDef.Color color, int position)
	{
		super(color, Piece.Type.KING, initialState(position, color), imageId(color));		
	}
	
	@Override
	public void attacks(List<Integer> squares, IMoves iMoves)
	{
		addValidCastlingMoves(squares, iMoves);
		
		Position pos = new Position(position());
		if(pos.incX())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		pos.position(position());
		if(pos.decX())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		
		pos.position(position());
		if(pos.incY())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		pos.position(position());
		if(pos.decY())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		
		pos.position(position());
		if(pos.incX() && pos.incY())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		pos.position(position());
		if(pos.incX() && pos.decY())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		
		pos.position(position());
		if(pos.decX() && pos.incY())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
		pos.position(position());
		if(pos.decX() && pos.decY())
		{
			addAttackIfValid(squares, pos.position(), iMoves);
		}
	}
	
	private static int imageId(ChessDef.Color color)
	{
		if(color == ChessDef.Color.BLACK)
		{
			return R.drawable.ic_black_king;
		}
		else
		{
			return R.drawable.ic_white_king;
		}
	}
	
	static private PieceState initialState(int position, ChessDef.Color color)
	{
		Position pos = new Position(position); 
		if(color == ChessDef.Color.BLACK)
		{
			return new PieceState(pos, (pos.y() != 0) || (pos.x() != 4));
		}
		else
		{
			return new PieceState(pos, (pos.y() != 7) || (pos.x() != 4));
		}
	}
	
	private void addValidCastlingMoves(List<Integer> squares, IMoves iMoves)
	{
		if((wasMoved() == false) && iMoves.isKingUnderAttack(color()) == false)
		{
			int position = position().position();
			
			//	check the short castling.
			if(iMoves.isEmptySquare(position + 1) && 
			   iMoves.isEmptySquare(position + 2) &&
			   iMoves.isPieceExist(Piece.Type.ROOK, color(), position + 3) &&
			   (iMoves.wasPieceMoved(position + 3) == false) &&
			   iMoves.isValidMove(this, position + 1) &&
			   iMoves.isValidMove(this, position + 2))
			{
				squares.add(position + 2);
			}
			
			//	check the long castling.
			if(iMoves.isEmptySquare(position - 1) && 
			   iMoves.isEmptySquare(position - 2) &&
			   iMoves.isEmptySquare(position - 3) &&
			   iMoves.isPieceExist(Piece.Type.ROOK, color(), position - 4) &&
			   (iMoves.wasPieceMoved(position - 4) == false) &&
				iMoves.isValidMove(this, position - 1) &&
				iMoves.isValidMove(this, position - 2))
			{
				squares.add(position - 2);
			}
		}
	}
	
	//	Next move is needed when a castling is done, in this case we need
	//	to move the rook.
	@Override
	public Move getExtraMove(IMoves iMoves)	
	{
		//	get info on the last king movement
		List<MoveInfo> moves = iMoves.currentMove();
		if(moves.size() != 1)
		{	//	 there is a castling only when only the king has moved.
			return null;
		}
		MoveInfo move = moves.get(0);
		//	short castling
		if(move.to() - move.from() == 2)
		{
			return new Move(move.to() + 1, move.to() - 1);
		}
		//	long castling
		else if((move.to() - move.from()) == -2)
		{
			return new Move(move.to() - 2, move.to() + 1);
		}
		return null;
	}
}